/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved.
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
         http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */

//
// Created by Wangyunlai on 2024/05/29.
//

#include "sql/expr/aggregator.h"
#include "common/log/log.h"
#include "common/type/attr_type.h"

RC SumAggregator::accumulate(const Value &value)
{
  if (value_.attr_type() == AttrType::UNDEFINED) {
    value_ = value;
    if (!value_.is_null()) {
      is_null_ = false;  // 只要有一个不是NULL，就设置标志位为false
    }
    return RC::SUCCESS;
  }

  // 这里处理NULL值
  if (value.is_null()) {
    LOG_TRACE("value is null, ignore it");
    return RC::SUCCESS;
  }

  // 只要有一个不是NULL，就设置标志位为false
  is_null_ = false;

  ASSERT(value.attr_type() == value_.attr_type(), "type mismatch. value type: %s, value_.type: %s", 
        attr_type_to_string(value.attr_type()), attr_type_to_string(value_.attr_type()));

  Value::add(value, value_, value_);
  return RC::SUCCESS;
}

RC SumAggregator::evaluate(Value &result)
{
  result = value_;
  result.set_null_flag(is_null_);
  return RC::SUCCESS;
}

RC CountAggregator::accumulate(const Value &value)
{
  /*这里只需要计数一下就可以*/
  if (value.is_null()) {
    LOG_TRACE("value is null, ignore it");
    return RC::SUCCESS;
  }
  cnt_++;
  return RC::SUCCESS;
}

RC CountAggregator::evaluate(Value &result)
{
  /*这里用cnt_来构造Value*/
  Value v(cnt_);
  result = v;
  return RC::SUCCESS;
}

RC AvgAggregator::accumulate(const Value &value)
{
  if (value_.attr_type() == AttrType::UNDEFINED) {
    value_ = value;
    if (value.is_null()) {
      is_null_ = true;  // 如果是NULL值，设置好标记位
    } else {
      is_null_ = false;  // 只要有一个不是NULL，就设置标志位为false
      cnt_++;            // 计数加1
    }
    return RC::SUCCESS;
  }

  // 这里处理NULL值
  if (value.is_null()) {
    LOG_TRACE("value is null, ignore it");
    return RC::SUCCESS;
  }

  // 只要有一个不是NULL，就设置标志位为false
  is_null_ = false;

  cnt_++;  // 计数加1
  ASSERT(value.attr_type() == value_.attr_type(), "type mismatch. value type: %s, value_.type: %s",
        attr_type_to_string(value.attr_type()), attr_type_to_string(value_.attr_type()));

  Value::add(value, value_, value_);
  return RC::SUCCESS;
}

RC AvgAggregator::evaluate(Value &result)
{
  if (is_null_) {
    result.set_null_flag(true);
    return RC::SUCCESS;
  }

  if (value_.attr_type() == AttrType::FLOATS || value_.attr_type() == AttrType::INTS) {
    float reg = value_.get_float();
    reg       = reg / cnt_;
    Value v(reg);
    result = v;
    return RC::SUCCESS;
  } else {
    LOG_ERROR("can not average with this type. type:%d", value_.attr_type());
    return RC::INVALID_ARGUMENT;
  }
}

RC MaxAggregator::accumulate(const Value &value)
{
  if (value_.attr_type() == AttrType::UNDEFINED) {
    value_ = value;
    if (!value_.is_null()) {
      is_null_ = false;  // 只要有一个不是NULL，就设置标志位为false
    }
    return RC::SUCCESS;
  }

  // 这里处理NULL值
  if (value.is_null()) {
    LOG_TRACE("value is null, ignore it");
    return RC::SUCCESS;
  }

  // 只要有一个不是NULL，就设置标志位为false
  is_null_ = false;

  if (value_.compare(value) < 0) {
    value_ = value;
  }
  return RC::SUCCESS;
}

RC MaxAggregator::evaluate(Value &result)
{
  // 如果是NULL值，设置好标记位
  if (is_null_) {
    result.set_null_flag(true);
    return RC::SUCCESS;
  }

  result = value_;
  return RC::SUCCESS;
}

RC MinAggregator::accumulate(const Value &value)
{
  if (value_.attr_type() == AttrType::UNDEFINED) {
    value_ = value;
    if (!value_.is_null()) {
      is_null_ = false;  // 只要有一个不是NULL，就设置标志位为false
    }
    return RC::SUCCESS;
  }

  // 这里处理NULL值
  if (value.is_null()) {
    LOG_TRACE("value is null, ignore it");
    return RC::SUCCESS;
  }

  // 只要有一个不是NULL，就设置标志位为false
  is_null_ = false;

  if (value_.compare(value) > 0) {
    value_ = value;
  }
  return RC::SUCCESS;
}

RC MinAggregator::evaluate(Value &result)
{

  // 如果是NULL值，设置好标记位
  if (is_null_) {
    result.set_null_flag(true);
    return RC::SUCCESS;
  }

  result = value_;
  return RC::SUCCESS;
}
